# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1153.67.18 -> 1.1153.67.19
#	arch/ia64/kernel/perfmon.c	1.57    -> 1.58   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/09/05	greg@kroah.com	1.1153.1.268
# Merge kroah.com:/home/linux/BK/bleed-2.5
# into kroah.com:/home/linux/BK/gregkh-2.6
# --------------------------------------------
# 03/09/05	eranian@hpl.hp.com	1.1153.67.19
# [PATCH] ia64: perfmon2 update
# 
# This patch fixes the following:
# 
#         - correct a bug in pfm_close() which was causing some per-process 
#           sessions to not unreserve on exit.
# 
#         - changed the permission checking to load a context to allow more
#           flexibility, modeled after ptrace_attach().
# --------------------------------------------
#
diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c	Tue Sep  9 01:05:28 2003
+++ b/arch/ia64/kernel/perfmon.c	Tue Sep  9 01:05:28 2003
@@ -1975,8 +1975,6 @@
 
 		PROTECT_CTX(ctx, flags);
 
-		/* reload state, may have changed during  opening of critical section */
-		state = ctx->ctx_state;
 
 		remove_wait_queue(&ctx->ctx_zombieq, &wait);
   		set_current_state(TASK_RUNNING);
@@ -2005,6 +2003,10 @@
 	}
 
 doit:	/* cannot assume task is defined from now on */
+
+	/* reload state, may have changed during  opening of critical section */
+	state = ctx->ctx_state;
+
 	/*
 	 * the context is still attached to a task (possibly current)
 	 * we cannot destroy it right now
@@ -2037,7 +2039,7 @@
 
 	DPRINT(("[%d] ctx_state=%d free_possible=%d vaddr=%p addr=%p size=%lu\n",
 		current->pid,
-		ctx->ctx_state,
+		state,
 		free_possible,
 		smpl_buf_vaddr,
 		smpl_buf_addr,
@@ -2362,10 +2364,23 @@
 static int
 pfm_bad_permissions(struct task_struct *task)
 {
-	/* stolen from bad_signal() */
-	return (current->session != task->session)
-	    && (current->euid ^ task->suid) && (current->euid ^ task->uid)
-	    && (current->uid ^ task->suid) && (current->uid ^ task->uid);
+	/* inspired by ptrace_attach() */
+	DPRINT(("[%d] cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n",
+		current->pid,
+		current->uid,
+		current->gid,
+		task->euid,
+		task->suid,
+		task->uid,
+		task->egid,
+		task->sgid));
+
+	return ((current->uid != task->euid)
+	    || (current->uid != task->suid)
+	    || (current->uid != task->uid)
+	    || (current->gid != task->egid)
+	    || (current->gid != task->sgid)
+	    || (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE);
 }
 
 static int